#include<iostream>
#include<queue>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
using namespace std;
#define NUM 5


template<class T>
class BlockQueue
{
  public:
    BlockQueue(int cap=NUM)
      :_cap(cap)
    {
      pthread_mutex_init(&_mutex,NULL);
      pthread_cond_init(&_full,nullptr);
      pthread_cond_init(&_empty, nullptr);
    }
    ~BlockQueue()
    {
      pthread_mutex_destroy(&_mutex);
      pthread_cond_destroy(&_full);
      pthread_cond_destroy(&_empty);
    }
  private:
    bool Isfull()//判断队列是否满
    {
      return _cap==_bq.size();
    }
    bool Isempty()//判断队列是否空
    {
      return _bq.empty();
    }
  public:
    //生产函数
    void push(const T& data)
    { 
      // 
      pthread_mutex_lock(&_mutex);
      while(Isfull())//满了不能生产，等待
      {
        pthread_cond_wait(&_full, &_mutex);
      }
      _bq.push(data);

      pthread_mutex_unlock(&_mutex);
      pthread_cond_signal(&_empty);//生产以后通知消费
    }
    //消费接口
    void pop(T& data)
    {
      
      pthread_mutex_lock(&_mutex);
      while(Isempty())//空了不能消费，等待
      {
        pthread_cond_wait(&_empty, &_mutex);
      }
      data = _bq.front();
      _bq.pop();
      pthread_mutex_unlock(&_mutex);
      pthread_cond_signal(&_full);//消费以后通知生产
    }
  private:
    queue<T> _bq;
    int _cap;
    pthread_mutex_t _mutex;//保护阻塞队列的互斥锁
    pthread_cond_t _full;
    pthread_cond_t _empty;
};


